#ifndef PROTOCOL_H
#define PROTOCOL_H

#ifndef NO_QT
#include <QTcpSocket>
#endif

#include <inttypes.h>
#include "shareheader.h"

/* header format
   first byte:
     ---      ----        -
   status     type   0:req, 1:rep

   second byte:
   generator id, not used

   third & fourth byte:
   reserved, not used

   packet format:
   header,
   *data,
   length

*/

#define P_STAT_MASK 0xe0	// 1110 0000
#define P_TYPE_MASK 0x1f	// 0001 1111
#define P_REQ_MASK  0x01	// 0000 1111

const int GenListenPort = 6600;
const int RstatListenPort = 6601;
const int GenRangeBase = 0x7fffffff / MaxGenCount;

// command type
enum eCommandType{
	STARTUP_REQ = 0,
	STARTUP_REP,
	RUN_REQ,
	RUN_REP,
	STOP_REQ,
	STOP_REP,
	PROFILE_REQ,
	PROFILE_REP,
	TPS_REQ,
	TPS_REP,
	RESP_REQ,
	RESP_REP,
	USER_REQ,
	USER_REP,
	STAT_REQ,
	STAT_REP,
	SUM_REQ,
	SUM_REP,
	N_COMMAND_TYPE
};

// packet header
typedef struct{
	uint8_t head;
	uint8_t genId; // not used, peeraddress instead
	uint16_t length;
}TPacketHeader, *PPacketHeader;

// packet struct
typedef struct{
	TPacketHeader header;
	uint8_t *data;
	uint32_t length; // this is very important
}TPacket, *PPacket;

// profile struct
typedef struct{
	TTranSetting tran_list[N_TRANSACTIONS]; // transaction percent
	int duration; // in secs
	int inc_user; 
	int inc_times;
	int count; // user count
	int range_start;  // the range of sth
	int range_end;
}TProfile, *PProfile;

// transaction info struct
typedef struct{
	int tps;
	double resp;
}TTranData, *PTranData;

// resource statistics struct
typedef struct{
	double cpu_ratio;
	double page_in;
	double page_out;
	double intr;
	double context_sw;
	double packet_in;
	double packet_out;
}TRstatData, *PRstatData;

// tps reply struct
typedef struct{
	int tps; 
	int sn; // serial number
}TTpsReply, *PTpsReply;

// resp reply struct
typedef struct{
	int tps;	// the average resp time makes sense only if the tps is known
	double resp; 
	int sn; // serial number
}TRespReply, *PRespReply;

// user reply struct
typedef struct{
	int user; 
	int sn; // serial number
}TUserReply, *PUserReply;

// res stat reply struct
typedef struct{
	// cpu, page, swap, intr, context switch, disk, ethernet 
}TStatReply, *PStatReply;

#define READ_BUFFER_SIZE 4096

// make packet
int protocol_make_pkt(TPacket& packet, uint8_t type, uint8_t status, uint8_t *data, uint32_t length);

// send packet
#ifndef NO_QT
int protocol_send_pkt(QTcpSocket *skt, TPacket& packet);
#else
int protocol_send_pkt(int skt, TPacket& packet);
#endif

// get status
int protocol_get_status(const TPacket& packet);

// two say and hear function. not used, due to sync communication does not work, to be debug

#endif
